package com.lute.controller;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.security.oauth2.common.json.JSONArray;
import org.springframework.security.oauth2.common.json.JSONException;
import org.springframework.security.oauth2.common.json.JSONObject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.lute.json.AccountingPeriodVerificationJSON;
import com.lute.model.Approver;
import com.lute.model.Employee;
import com.lute.model.EmployeeAccountingPeriod;
import com.lute.model.EmployeeAccountingPeriodState;
import com.lute.model.User;
import com.lute.model.UserEntitlement;
import com.lute.utils.DAOFactory;
import com.lute.utils.ServerErrorResponse;

@Controller
public class AccountingPeriodApproveServlet {
	
	@RequestMapping (value="/approve",method= RequestMethod.POST, headers = "Content-type=application/json")
	public @ResponseBody String accountingPeriodChecked(@RequestBody String dataJSON, HttpServletRequest request) throws JSONException {
		String result = "";
		String from;
		JSONObject jsonReq;
		JSONObject jsonRes  = new JSONObject();
		
		HttpSession session = request.getSession(false);
		if(session == null) {
			jsonRes.put("result", ServerErrorResponse.USER_NOT_LOGGED_IN.toString());
			result = jsonRes.toString();
			return result;
		}
		
		System.out.println(dataJSON);
		
		try {
			jsonReq = new JSONObject(dataJSON);
			from = jsonReq.getString("from");
		} catch(JSONException e) {
			jsonRes.put("result", ServerErrorResponse.MALFORMED_REQUEST.toString());
			result = jsonRes.toString();
			return result;
		}
		
		/* check if json data was not malformed */
		if( (jsonReq.isNull("userIds")) && (jsonReq.isNull("from")) ) {
			jsonRes.put("result",ServerErrorResponse.MALFORMED_REQUEST.toString());
			result = jsonRes.toString();
			return result;
		}
		
		String role = (String)session.getAttribute("role");
		int sessionUserId = (Integer)session.getAttribute("sessionUserId");
		jsonRes.put("result", "");
		
		/* check  authorization */
		if(!(role.equals("approver"))) {
			jsonRes.put("result", ServerErrorResponse.USER_NOT_ENTITLED.toString());
			result = jsonRes.toString();
			return result;
		}
		
		try {
			
			Approver approver = Approver.getApproverWithEmployeesFromDB("id_user", sessionUserId);
			List<Employee> employees = approver.getEmployees();
			List<User> users = new ArrayList<User>();
			for(Employee employee: employees) {
				users.add(employee);
			}
			users.add(approver);
			
			List<EmployeeAccountingPeriod> employeePeriods = EmployeeAccountingPeriod.getEmployeeAccountingPeriodsFromDB(users,from);
			
			if(employeePeriods == null) {
				jsonRes.put("result", ServerErrorResponse.UNKNOWN_ACCOUNTING_PERIOD.toString());
				result = jsonRes.toString();
				System.out.println(result);
				return result;
			}
			
			employeePeriods = EmployeeAccountingPeriod.getEmployeeAccountingPeriodsWithEntriesFromDB(employeePeriods);
			
			for(EmployeeAccountingPeriod period : employeePeriods) {
				
				EmployeeAccountingPeriod.doAccountingPeriodVerification(period, jsonRes);
				
				if(!(jsonRes.get("result").equals(""))) {
					result = jsonRes.toString();
					System.out.println(result);
					return result;
				}
			}
			
			try {
				EmployeeAccountingPeriod.updateInDB(employeePeriods);
			} catch(IllegalStateException e) {
				jsonRes.put("result", ServerErrorResponse.OPERATION_NOT_ALLOWED.toString());
				result = jsonRes.toString();
				System.out.println(result);
				return result;
			}
		}
		catch(NullPointerException npe) {
			jsonRes.put("result", ServerErrorResponse.INTERNAL_ERROR.toString());
			result = jsonRes.toString();
			System.out.println(result);
			return result;
		}
		
		jsonRes.put("result","OK");
		result = jsonRes.toString();
		return result;
	}
}
